package com.rabbitmq.exchange.direct;

import com.rabbitmq.client.*;
import com.rabbitmq.utils.RabbitMQUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Receive01 {
    public static void main(String[] args) {
        //创建工厂对象用于指定链接的信息
        //创建链接以及通道,并添加异常处理同时在try..catch执行完成后自动释放资源
        try{
            final Connection connection = RabbitMQUtils.getConnection();
            Channel channel=connection.createChannel();
            /**
             * 声明一个队列
             *  参数 1 为队里名称 取值任意,如果这个名称已经存在则放弃创建,否则在MQ服务器中创建这个队列
             *  参数 2 为是否持久化的队列
             *  参数 3 为是否排外的队列true表示排外同时最多只允许有1个消费者监听这个队列
             *  参数 4 为是否自动删除 true为自动删除 当没有消费者监听这个队列时将自动删除队列以及消息
             *  参数 5 为队列的属性设置通常为null即可
             *  注意:
             *    这个行代码是可选代码,要在绑定交换机前和接收前确保存在
             */
            String queueName="directQueue";
            channel.queueDeclare(queueName,true,false,false,null);
            /**
             * 声明一个交换机
             * 参数 1 为交换机名称 取值任意,如果这个名称已经存在则放弃创建,否则在MQ服务器中创建这个交换机
             * 参数 2 交换机类型 取值为 direct fanout  topic  headers
             * 参数 3 为是否持久化的交换机
             * 注意:
             *    这个行代码是可选代码,但是要在绑定队列前确保存在
             */
            String  exchangeName="directExchange";
            channel.exchangeDeclare(exchangeName,"direct",true);
            /**
             * 将队列和交换机进行绑定
             * 参数 1 为队列名称
             * 参数 2 为交换机名称
             * 参数 3 为路由表中的绑定键(BindingKey)
             * 注意:
             *    这个行代码是可选代码,但是要在监听队列前确保正确绑定否则无法接收消息
             */
            channel.queueBind(queueName, exchangeName,"directKey");
                /**
                 * 监听队列接收消息
                 * 参数 1 为需要监听的队列名称
                 * 参数 2 为消息是否自动确认 true表示自动确认,只要消息接收完成无论是否完成处理都会讲消息从队列中移除
                 * 参数 3 回调函数,利用这个回调来完成具体的消息处理(参数为对象类型)
                 * 注意:
                 *   1.接收消息前需要确保队列已经存在
                 *   2.basicConsume在底层会启动一个子线程来持续性接收消息,因此不能关闭通道或链接
                 */
            channel.basicConsume(queueName,true,new DefaultConsumer(channel){
                /**
                 * 消息处理的方法
                 */
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    //获取消息
                    String message=new String(body);
                    //处理消息,消息处理有很多种方法例如写入数据库等等
                    System.out.println("Receive01:\t"+message);
                }
            });
            System.out.println("消息接收成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
